package org.base.sys.service.impl;

import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.base.ConstantPool;
import org.base.common.service.impl.ServiceImpl;
import org.base.common.util.ObjectCopyUtils;
import org.base.common.util.TreeUtils;
import org.base.sys.VO.SysMenuPermissionVO;
import org.base.sys.VO.TreeMenuVO;
import org.base.sys.constant.SysConstant;
import org.base.sys.dao.SysMenuPermissionMapper;
import org.base.sys.pojo.SysMenuPermission;
import org.base.sys.query.SysMenuPermissionQuery;
import org.base.sys.service.SysMenuPermissionService;
import org.base.sys.service.SysRoleMenuPermissionService;
import org.base.sys.service.SysUserRoleService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 菜单权限表 服务实现类
 * </p>
 *
 * @author AutoGenerator
 * @since 2020-05-27
 */
@Service
@Slf4j
@AllArgsConstructor
public class SysMenuPermissionServiceImpl extends ServiceImpl<SysMenuPermissionMapper, SysMenuPermission, SysMenuPermissionQuery> implements SysMenuPermissionService {

    private SysRoleMenuPermissionService roleMenuPermissionService;

    private SysUserRoleService userRoleService;


    @Override
    public List<SysMenuPermission> getMenus() {
        return lambdaQuery().ne(SysMenuPermission::getType, ConstantPool.BUTTON).orderByAsc(SysMenuPermission::getSeq).list();
    }

    @Override
    public List<SysMenuPermission> getVisibleMenus() {
        return lambdaQuery().ne(SysMenuPermission::getType, ConstantPool.BUTTON)
                .eq(SysMenuPermission::getVisible, 1)
                .orderByAsc(SysMenuPermission::getSeq).list();
    }

    @Override
    public List<TreeMenuVO> getTreeMenu() {
        final List<SysMenuPermission> menus = getMenus();
        if (CollectionUtils.isNotEmpty(menus)) {
            final List<TreeMenuVO> menuVOS = ObjectCopyUtils.copy(menus, TreeMenuVO.class, v -> {
            });
            List<TreeMenuVO> treeMenus = TreeUtils.newTree(menuVOS, Long.valueOf(0), TreeMenuVO::getParentId, TreeMenuVO::getId, TreeMenuVO::setChildren);
            return treeMenus;
        }
        return Collections.EMPTY_LIST;
    }

    @Override
    public boolean hide(Long id) {
        return switchVisible(id, 0);
    }

    @Override
    public boolean show(Long id) {
        return switchVisible(id, 1);
    }

    public boolean switchVisible(Long id, Integer visible) {
        return lambdaUpdate().eq(SysMenuPermission::getId, id)
                .set(SysMenuPermission::getVisible, visible)
                .update();
    }

    @Override
    @Transactional
    public boolean saveOrUpdate(SysMenuPermission entity) {
        final Long id = entity.getId();
        if (id != null) {
            final SysMenuPermission menuPermission = getById(id);
            if (entity.getParentId() != null) {
                menuPermission.setParentId(entity.getParentId());
            }
            menuPermission.setName(entity.getName());
            menuPermission.setPermKey(entity.getPermKey());
            menuPermission.setSeq(entity.getSeq());
            menuPermission.setPath(entity.getPath());
            menuPermission.setRedirect(entity.getRedirect());
            menuPermission.setIcon(entity.getIcon());
            menuPermission.setComponent(entity.getComponent());
            menuPermission.setVisible(entity.getVisible());
            return super.saveOrUpdate(menuPermission);
        } else {
            return super.saveOrUpdate(entity);
        }
    }

    @Override
    public List<SysMenuPermission> getParenMenus(Long parentId) {
        final SysMenuPermission menuPermission = getById(parentId);
        if (menuPermission != null) {
            final Long pId = menuPermission.getParentId();
            return lambdaQuery().eq(SysMenuPermission::getParentId, pId).list();
        }
        return Collections.emptyList();
    }

    @Override
    public List<SysMenuPermission> getVisibleMenuPermission() {
        return lambdaQuery()
                .eq(SysMenuPermission::getVisible, 1)
                .orderByAsc(SysMenuPermission::getSeq).list();
    }

    @Override
    public List<SysMenuPermissionVO> getTreeMenuPermission() {
        final List<SysMenuPermission> menus = getVisibleMenuPermission();
        if (CollectionUtils.isNotEmpty(menus)) {
            final List<SysMenuPermissionVO> menuPermissionVOS = ObjectCopyUtils.copy(menus, SysMenuPermissionVO.class, v -> {
            });
            List<SysMenuPermissionVO> treeMenus = TreeUtils.newTree(menuPermissionVOS, Long.valueOf(0), SysMenuPermissionVO::getParentId, SysMenuPermissionVO::getId, SysMenuPermissionVO::setChildren);
            menuPermissionVOS.forEach(e -> {
                if (CollectionUtils.isEmpty(e.getChildren())) {
                    e.setChildren(null);
                }
            });
            return treeMenus;
        }
        return Collections.EMPTY_LIST;
    }

    @Override
    public List<String> getRolePermissions(List<Long> roleIds) {
        return getRolePerms(roleIds)
                .stream()
                .map(SysMenuPermission::getPermKey)
                .collect(Collectors.toList());
    }

    @Override
    public List<SysMenuPermission> getVisibleMenuByIds(List<Long> menuIds) {
        if (CollectionUtils.isNotEmpty(menuIds)) {
            return lambdaQuery().ne(SysMenuPermission::getType, ConstantPool.BUTTON)
                    .in(SysMenuPermission::getId, menuIds)
                    .eq(SysMenuPermission::getVisible, 1)
                    .list();

        }
        return Collections.emptyList();
    }

    @Override
    public List<SysMenuPermission> getRolePerms(List<Long> roleIds) {
        List<Long> menuPermissionIds = roleMenuPermissionService.getRolesMenuPermissionIds(roleIds);
        return lambdaQuery().in(SysMenuPermission::getId, menuPermissionIds)
                .eq(SysMenuPermission::getType, ConstantPool.BUTTON)
                .list();

    }

    @Override
    public List<SysMenuPermission> getAllPerms() {
        return lambdaQuery()
                .eq(SysMenuPermission::getVisible, 1)
                .eq(SysMenuPermission::getType, ConstantPool.BUTTON)
                .list();
    }

    @Override
    public List<SysMenuPermission> getPerms() {
        List<SysMenuPermission> result = new ArrayList<>();
        SysMenuPermission sysMenuPermission = new SysMenuPermission();
        sysMenuPermission.setPermKey(SysConstant.ANON);
        result.add(sysMenuPermission);
        sysMenuPermission = new SysMenuPermission();
        sysMenuPermission.setPermKey(SysConstant.LOGIN);
        result.add(sysMenuPermission);
        sysMenuPermission = new SysMenuPermission();
        sysMenuPermission.setPermKey(SysConstant.DENY);
        result.add(sysMenuPermission);
        result.addAll(getAllPerms());
        return result;
    }

    @Override
    public List<SysMenuPermission> getVisibleMenuPermByIds(List<Long> menuIds) {
        if (CollectionUtils.isNotEmpty(menuIds)) {
            return lambdaQuery().in(SysMenuPermission::getId, menuIds)
                    .eq(SysMenuPermission::getVisible, 1)
                    .list();

        }
        return Collections.emptyList();
    }
}
